package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;
	@Autowired
	private VodService vodService;
	@Autowired
	private AlbumInfoMapper albumInfoMapper;
	@Autowired
	private TrackStatMapper trackStatMapper;
	@Autowired
	private UserInfoFeignClient userInfoFeignClient;
	//修改
	@Override
	public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {

		TrackInfo trackInfo = getById(trackId);
		//获取原有的声音id
		String mediaFileId = trackInfo.getMediaFileId();
		//拷贝
		BeanUtils.copyProperties(trackInfoVo, trackInfo);
		if (!mediaFileId.equals(trackInfoVo.getMediaFileId())){
			//修改了,删除原有
			vodService.removeMediaByFileId(mediaFileId);
			//获取新的流媒体数据
			TrackMediaInfoVo mediaInfo = vodService.gateMediaInfo(trackInfoVo.getMediaFileId());
			trackInfo.setMediaDuration(mediaInfo.getDuration());
			trackInfo.setMediaSize(mediaInfo.getSize());
			trackInfo.setMediaFileId(trackInfoVo.getMediaFileId());
			trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
		}
		//更新声音
		trackInfoMapper.updateById(trackInfo);
	}

	//删除
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeTrackInfo(Long trackId) {
		//获取声音信息
		TrackInfo trackInfo = getById(trackId);
		removeById(trackId);
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId,trackId));
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()-1);
		albumInfoMapper.updateById(albumInfo);
		//维护
		trackInfoMapper.updateOrderNum(trackInfo.getAlbumId(),trackInfo.getOrderNum());
        //重试机制
		try {
            vodService.removeMediaByFileId(trackInfo.getMediaFileId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
	//查看声音列表

	@Override
	public void findUserTrackPage(Page<TrackListVo> trackListVoPage, TrackInfoQuery trackInfoQuery) {
		trackInfoMapper.selectUserTrackPage(trackListVoPage, trackInfoQuery);
	}
	//保存
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
		//track_info
		TrackInfo trackInfo = new TrackInfo();
		//拷贝
		BeanUtils.copyProperties(trackInfoVo, trackInfo);
		trackInfo.setUserId(userId);
		//获取专辑对象
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
		trackInfo.setOrderNum(albumInfo.getIncludeTrackCount()+1);
		//给流媒体数据赋值
		TrackMediaInfoVo mediaInfo = vodService.gateMediaInfo(trackInfoVo.getMediaFileId());
		//判断
		if (null != mediaInfo){
			trackInfo.setMediaDuration(mediaInfo.getDuration());
			trackInfo.setMediaSize(mediaInfo.getSize());
			trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
			trackInfo.setMediaType(mediaInfo.getType());
		}
		trackInfoMapper.insert(trackInfo);
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()+1);
		albumInfoMapper.updateById(albumInfo);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT);


	}

	private void saveTrackStat(Long id, String trackStatComment) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(id);
		trackStat.setStatType(trackStatComment);
		trackStat.setStatNum(new Random().nextInt(100));
		trackStatMapper.insert(trackStat);
	}

	@Override
	public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> trackListVoPage, Long albumId, Long userId) {
		/**
		 获取专辑下的声音列表
		 判断用户是否购买了该专辑
		 */
		IPage<AlbumTrackListVo> pageInfo = trackInfoMapper.selectAlbumTrackPage(trackListVoPage, albumId);
		//根据专辑id获取专辑对象
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		//判断是否登录
		if (userId != null){
			//未登录 判断类型
			String payType = albumInfo.getPayType();
			if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)){
				//  vip免费 或 付费 除了试听集数外，都应该付费！
				//  获取免费的试听集数
				Integer tracksForFree = albumInfo.getTracksForFree();
				for (AlbumTrackListVo albumTrackListVo : pageInfo.getRecords()) {
					if (albumTrackListVo.getOrderNum() > tracksForFree){
						//设置成付费
						albumTrackListVo.setIsShowPaidMark(true);
					}
				}
			}
		}else {
			//  专辑： 免费，付费，vip免费
			//  用户登录    获取用户信息
			Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
			//判断
			Assert.notNull(userInfoVoResult, "用户信息不存在");
			UserInfoVo userInfoVo = userInfoVoResult.getData();
			Assert.notNull(userInfoVo, "用户信息对象不存在");
			//声明一个付费标识
			Boolean isPaid = false;
			//判断专辑是否是VIP免费
			if (SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())){
				//  用户是否是vip - 不属于vip 或 是vip但已过期；需要收费
				if (userInfoVo.getIsVip()==0 || userInfoVo.getIsVip()==1 && userInfoVo.getVipExpireTime().before(new Date())){
					isPaid = true;
				}
			}else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())){
				//要付费
				isPaid = false;
			}
			//统一处理付费情况
			if (isPaid){
				//  需要付费！
				//  1.  免费试听集数有多少集； 2.  用户是否购买过专辑(userId,albumId)user_paid_album，或购买过声音 user_paid_track！
				Integer tracksForFree = albumInfo.getTracksForFree();
				List<AlbumTrackListVo> albumTrackListVoList = pageInfo.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree).collect(Collectors.toList());
				List<Long> isNeedPaidTrackListVoList = albumTrackListVoList.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
				//远程调用
				Result<Map<Long,Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(albumId,isNeedPaidTrackListVoList);
				Assert.notNull(mapResult, "用户付费信息不存在");
				Map<Long, Integer> map = mapResult.getData();
				for (AlbumTrackListVo albumTrackListVo : albumTrackListVoList) {
					boolean flag = map.get(albumTrackListVo.getTrackId())== 1 ? false:true;
					albumTrackListVo.setIsShowPaidMark(flag);
				}
			}
		}
		return pageInfo;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
		//update track_stat set stat_num=stat_num+1 where track_id=1 and stat_type='0701' and is_deleted=0;
		trackStatMapper.updateTrackStat(trackStatMqVo.getTrackId(), trackStatMqVo.getStatType(), trackStatMqVo.getCount());
		//更新专辑播放量
		if (SystemConstant.TRACK_STAT_PLAY.equals(trackStatMqVo.getStatType())){
			//专辑播放量
			albumInfoMapper.updateAlbumStat(trackStatMqVo.getAlbumId(),SystemConstant.TRACK_STAT_PLAY, trackStatMqVo.getCount());
		}else if (SystemConstant.TRACK_STAT_COLLECT.equals(trackStatMqVo.getStatType())){

		}
	}
}
